<template>
  <FullPageModal
    :get-container="getContainer"
    mask
    inset-cls="!inset-x-4 !inset-y-4"
    :ok-disabled="okDisabled"
    @ok="handleOk"
    @update:visible="handleVisible"
  >
    <RelateOrder
      ref="relateOrderIns"
      :receipt-type="receiptType"
      :options="relateOptions"
      @select="handleRelateSelect"
      @init="relateOrderInit"
      @relate="isRelated = true"
    />
    <div class="relative">
      <DynamicForm
        ref="wrFormIns"
        :model="model"
        :model-form-setting="modelFormSetting"
        :columns="columns"
        is3-col
        :disable-keys="isRelated ? disableKeysAfterRelated : []"
        @init="wrFormInit"
      ></DynamicForm>
      <div class="mb-4">
        <a-tooltip :title="supplierFilter ? (curSupplier ? '' : '请先选择供应商') : ''">
          <a-button
            type="primary"
            :disabled="(supplierFilter ? !curSupplier : false) || (isRelated && disableAddGoodAfterRelated)"
            @click="showChooseProduct"
          >
            新增商品
          </a-button>
        </a-tooltip>
      </div>
      <div class="h-120 border border-solid border-gray-200">
        <component
          :is="targetTableComp"
          v-if="targetTableComp"
          ref="receiptTableIns"
          :data="productData"
          :summary-data="summaryData"
          :model="model"
          :disable-oper="isRelated && disableAddGoodAfterRelated"
          @remove="removeProduct"
        />
      </div>
      <div
        v-if="isRequiredRelate && !isRelated"
        class="absolute inset-0 bg-white bg-opacity-80 z-10 rounded-lg flex items-center justify-center"
      >
        <div class="text-2xl">请先关联{{ relateName }}</div>
      </div>
    </div>
    <div class="mt-4 text-lg font-semibold">
      <span>制单人:</span>
      <span class="ml-2">{{ tabulator }}</span>
      <span class="ml-7">制单时间:</span>
      <span class="ml-2">{{ tabulationTime }}</span>
    </div>
    <div v-if="wrId" class="mt-4 text-lg font-semibold">
      <span>审核人:</span>
      <span class="ml-2">{{ reviewer || "--" }}</span>
      <span class="ml-7">审核时间:</span>
      <span class="ml-2">{{ reviewTime }}</span>
    </div>
    <a-modal
      v-model:visible="productSelVisible"
      :title="curSupplier ? `新增商品(${curSupplier.name})` : '新增商品'"
      :width="800"
      :body-style="{ padding: 0 }"
      @ok="handleSel"
    >
      <TableSelect
        ref="tableSelectIns"
        v-model:value="selProductIds"
        search-placeholder="搜索商品名称或编码"
        search-key="keywords"
        :extra-params="productExtraParams"
        :columns="selProductColumns"
        :get-page-url="Api.productFilePage"
        :field-names="{ value: 'id', label: 'name' }"
        :is-item-disabled="isItemDisabled"
      ></TableSelect>
    </a-modal>
    <a-modal
      v-model:visible="operatorSelVisible"
      :title="'选择' + operatorText"
      :width="800"
      :body-style="{ padding: 0 }"
      @ok="handleOperatorSel"
    >
      <TableSelect
        ref="operatorSelIns"
        v-model:value="selOperatorIds"
        search-placeholder="搜索用户名/昵称/手机号"
        search-key="keywords"
        :columns="selOperatorColumns"
        :get-page-url="systemApi.usersPage"
        :field-names="{ value: 'id', label: 'nickname' }"
        single-select
      ></TableSelect>
    </a-modal>
  </FullPageModal>
</template>
<script setup lang="ts">
import { computed, onMounted, ref, watch, nextTick, h, DefineComponent } from "vue";
import {
  DeliveryType,
  ReceiptType,
  type ProductFileItem,
  type ReceiptItem,
  AdjustmentType,
  ProfitLossType,
  PurchaseOrderType,
  GoodsSaleType,
  WarehouseItem,
  SupplierItem,
} from "/@/api/main/pis/models";
import {
  Api,
  getSupplierList,
  getWarehouseList,
  addWarehousingReceipt,
  getWarehousingReceipt,
  updateWarehousingReceipt,
} from "/@/api/main/pis";
import { Api as systemApi } from "/@/api/main/system";
import { DynamicFormExpose, FormItemComponentType, FormItemData } from "/@/components/CURDDialog/models";
import { TableColumnProps, TableProps, message } from "ant-design-vue";
import { SelectExpose } from "/@/types/components";
import dayjs, { Dayjs } from "dayjs";
import { cloneDeep } from "lodash-es";
import { enumToOptions, getFloatInteger, intlNumberFormat, isNullOrUndefOrEmpty } from "/@/utils/common";
import { useReceiptForm } from "./useReceiptForm";
import authCache from "/@/utils/cache/authCache";
import SelectInput from "/@/components/common/SelectInput.vue";
import { UserItem } from "/@/api/main/system/models";
import RelateOrder from "./RelateOrder.vue";
import DeliveryReceiptTable from "./DeliveryReceiptTable.vue";
import WarehousingReceiptTable from "./WarehousingReceiptTable.vue";
import ReturnReceiptTable from "./ReturnReceiptTable.vue";
import AdjustmentReceiptTable from "./AdjustmentReceiptTable.vue";
import ProfitLossReceiptTable from "./ProfitLossReceiptTable.vue";
import PurchaseReceiptTable from "./PurchaseReceiptTable.vue";
import SellReceiptTable from "./SellReceiptTable.vue";
import { ReceiptTableExpose, RelateOrderExpose, RelateOrderOptions } from "./useReceiptManage";
import { FinancialType } from "/@/api/main/financial/models";
import { getFinancialDetail } from "/@/api/main/financial";

const props = defineProps<{
  columns: TableColumnProps<any>[];
  reloadTable: (params?: any) => void;
  wrId?: number;
  receiptType: ReceiptType;
}>();

const okDisabled = ref(false);
const tableComps: Record<ReceiptType, any> = {
  [ReceiptType.delivery]: DeliveryReceiptTable,
  [ReceiptType.warehousing]: WarehousingReceiptTable,
  [ReceiptType.return]: ReturnReceiptTable,
  [ReceiptType.adjustment]: AdjustmentReceiptTable,
  [ReceiptType.profitLoss]: ProfitLossReceiptTable,
  [ReceiptType.purchase]: PurchaseReceiptTable,
  [ReceiptType.sell]: SellReceiptTable,
};
const targetTableComp = tableComps[props.receiptType];

const emits = defineEmits(["update:visible"]);
const receiptTableIns = ref<ReceiptTableExpose>();

function handleVisible(visible: boolean) {
  emits("update:visible", visible);
  if (visible) {
    if (props.wrId) {
      //编辑
      getDetail();
    } else {
      relateOptions.value = { reset: true };
      startTabulationTime();
    }
  } else {
    isRelated.value = false;
    if (wrFormIns.value) {
      wrFormIns.value.resetFields();
    }
    productData.value = [];
    stopTabulationTime();
  }
}

function getContainer() {
  return document.body;
}
/**
 * 关联订单
 */
const relateOrderIns = ref<RelateOrderExpose>();
const relateOptions = ref<RelateOrderOptions>({});
const isRelated = ref(false);
const isRequiredRelate = ref(false);
let relateReceiptType: ReceiptType | null = null;
let relateFinancialType: FinancialType | null = null;
const relateName = ref("");
const disableKeysAfterRelated = ref<string[]>([]);
const disableAddGoodAfterRelated = ref(false);
function relateOrderInit(e: {
  requiredRelate: boolean;
  relateReceiptType: ReceiptType | null;
  relateName: string;
  relateFinancialType: FinancialType | null;
  disableFormKeys: string[];
  disableAddGood: boolean;
}) {
  isRequiredRelate.value = e.requiredRelate;
  relateReceiptType = e.relateReceiptType;
  relateName.value = e.relateName;
  relateFinancialType = e.relateFinancialType;
  disableKeysAfterRelated.value = e.disableFormKeys;
  disableAddGoodAfterRelated.value = e.disableAddGood;
}
// const disableKeysAfterRelated = computed(() => {
//   if (isRelated.value) {
//     if (props.receiptType === ReceiptType.warehousing) {
//       return ["supplierId", "warehouseId"];
//     }
//   }
//   return null;
// });
function handleRelateSelect(item: any) {
  if (!item) {
    isRelated.value = false;
    //取消关联 清空数据
    if (wrFormIns.value) {
      wrFormIns.value.resetFields();
    }
    productData.value = [];
    return;
  }
  isRelated.value = true;
  if (relateReceiptType) {
    getDetail(item.id, relateReceiptType);
  } else if (relateFinancialType) {
    getDetailByFinancial(item.id, relateFinancialType);
  }
}
/**
 * 表单
 */
const wrFormIns = ref<DynamicFormExpose>();
const { model, modelFormSetting, supplierData, warehouseData, operatorKey, operatorText, operatorSelVisible } =
  useReceiptForm(props.receiptType);

function wrFormInit() {
  if (wrFormIns.value) {
    wrFormIns.value.initFormItemComponentData();
  }
}
/**
 * 获取详情
 * @param targetWrId 不传则获取当前单详情，传了则获取所传单的详情
 */
async function getDetail(relateWrId?: number, relateReceiptType?: ReceiptType) {
  const data = await getWarehousingReceipt(
    relateWrId || (props.wrId as number),
    relateReceiptType || props.receiptType
  );
  if (data) {
    //处理只存name的旧数据
    if (data.supplierName && !data.supplierId && supplierData.value) {
      const item = supplierData.value.find((el) => el.name === data.supplierName);
      if (item) {
        data.supplierId = item.id;
      }
    }
    if (relateWrId) {
      for (let key in model.value) {
        //目标单数据覆盖当前单数据
        if (!isNullOrUndefOrEmpty(data[key])) {
          model.value[key] = data[key];
        }
      }
      const idKeys = ["warehouseAdminId"];
      idKeys.forEach((key) => {
        if (data[key]) {
          model.value[key] = data[key];
        }
      });
      relateOrderIns.value?.relateCurReceipt(model.value, data);
    } else {
      for (let key in model.value) {
        if (
          key === "warehousingDate" ||
          key === "deliveryDate" ||
          key === "tabulationTime" ||
          key === "returnsDate" ||
          key === "adjustmentDate" ||
          key === "profitLossDate" ||
          key === "saleDate"
        ) {
          if (data[key]) {
            model.value[key] = dayjs(data[key]).format("YYYY-MM-DD HH:mm:ss");
          }
        } else {
          model.value[key] = data[key];
        }
      }
      reviewer.value = data.reviewer;
      reviewTime.value = data.reviewTime ? dayjs(data.reviewTime).format("YYYY-MM-DD HH:mm:ss") : "--";
    }
    data.details.forEach((item) => {
      if (data.batchDetails) {
        const target = data.batchDetails.find((el) => el.productId === item.productId);
        if (target) {
          Object.assign(item, target);
        }
      }
      if (item.shelfLife) {
        item._shelfLife = dayjs(item.shelfLife);
      }
      if (item.productDate) {
        item._productDate = dayjs(item.productDate);
      }
    });
    productData.value = data.details;
    tabulationTime.value = dayjs(data.tabulationTime).format("YYYY-MM-DD HH:mm:ss");
    if (!relateWrId) {
      relateOptions.value = { curReceipt: data };
    }
  }
}
async function getDetailByFinancial(id: number, financialType: FinancialType) {
  const data = await getFinancialDetail({ id }, financialType);
  if (data) {
    for (let key in model.value) {
      //目标单数据覆盖当前单数据
      if (!isNullOrUndefOrEmpty(data[key])) {
        model.value[key] = data[key];
      }
    }
    relateOrderIns.value?.relateCurReceipt(model.value, data);
  }
}
/**
 * 根据供应商过滤商品数据
 */
const supplierFilter = ref(props.receiptType === ReceiptType.warehousing || props.receiptType === ReceiptType.purchase);
const curSupplier = computed(() => {
  if (wrFormIns.value) {
    if (supplierData.value) {
      const item = supplierData.value.find(
        (el) => el.name === model.value.supplierName || el.id === model.value.supplierId
      );
      return item || null;
    }
  }
  return null;
});
const productExtraParams = computed(() => {
  return curSupplier.value ? { supplierId: curSupplier.value.id } : {};
});
watch(productExtraParams, () => {
  nextTick(() => {
    if (tableSelectIns.value && supplierFilter.value) {
      tableSelectIns.value.reload();
    }
  });
});
/**
 * 商品表格
 */
const productData = ref<Partial<ProductFileItem>[]>([]);
watch(
  productData,
  (data) => {
    if (data.length === 0) {
      summaryData.value = void 0;
      return;
    }
    let orderQuantity = 0;
    let warehousingQuantity = 0;
    let warehousingAmount = 0;
    //
    let deliveryQuantity = 0;
    let price = 0;
    let amount = 0;
    //
    let returnsQuantity = 0;
    let discountAmount = 0;
    let returnsAmount = 0;
    //
    let adjustmentQuantity = 0;
    //
    let profitLossQuantity = 0;
    let profitLossAmount = 0;
    //
    let orderAmount = 0;
    let buyingPrice = 0;
    //
    let saleQuantity = 0;
    data.forEach((item) => {
      orderQuantity += Number(item.orderQuantity || 0);
      warehousingQuantity += Number(item.warehousingQuantity || 0);
      warehousingAmount += Number(item.warehousingAmount || 0);

      deliveryQuantity += Number(item.deliveryQuantity || 0);
      price += Number(item.price || 0);
      amount += Number(item.amount || 0);

      returnsQuantity += Number(item.returnsQuantity || 0);
      discountAmount += Number(item.discountAmount || 0);
      returnsAmount += Number(item.returnsAmount || 0);

      adjustmentQuantity += Number(item.adjustmentQuantity || 0);

      profitLossQuantity += Number(item.profitLossQuantity || 0);
      profitLossAmount += Number(item.profitLossAmount || 0);

      orderAmount += Number(item.orderAmount || 0);
      buyingPrice += Number(item.buyingPrice || 0);

      saleQuantity += Number(item.saleQuantity || 0);
    });
    const result: Partial<ProductFileItem> = {
      orderQuantity,
      warehousingQuantity,
      warehousingAmount,
      deliveryQuantity,
      price,
      amount,
      returnsQuantity,
      discountAmount,
      returnsAmount,
      adjustmentQuantity,
      profitLossQuantity,
      profitLossAmount,
      orderAmount,
      buyingPrice,
      saleQuantity,
    };
    // for (let i in result) {
    //   if (typeof result[i] == "number") {
    //     result[i] = intlNumberFormat(result[i]);
    //   }
    // }
    summaryData.value = result;
  },
  { deep: true }
);
const summaryData = ref<Partial<ProductFileItem>>();
/**
 * 选择商品
 */
const tableSelectIns = ref<SelectExpose>();
const productSelVisible = ref(false);
const selProductIds = ref<number[]>([]);
const selProductColumns = ref<TableColumnProps<ProductFileItem>[]>([
  {
    title: "供应商",
    dataIndex: "supplierName",
  },
  {
    title: "品名",
    dataIndex: "name",
  },
  {
    title: "类别",
    dataIndex: "mallClass",
  },
  {
    title: "类型",
    dataIndex: "productType",
  },
  {
    title: "条码",
    dataIndex: "barCode",
  },
  {
    title: "编码",
    dataIndex: "productCode",
  },
]);
function showChooseProduct() {
  productSelVisible.value = true;
}
function handleSel() {
  if (selProductIds.value.length === 0) {
    return message.info("请至少选择一个商品");
  }
  if (tableSelectIns.value) {
    const items = tableSelectIns.value.getSelecedItems() as ProductFileItem[];
    const newData: Partial<ProductFileItem>[] = [];
    items.forEach((item) => {
      newData.push({
        productId: item.id,
        productCode: item.productCode,
        barCode: item.barCode,
        measurementUnit: item.measurementUnit,
        specifications: item.specifications,
        validityCriteria: item.validityCriteria,
        name: item.name,
        orderQuantity: 0,
        warehousingQuantity: 0,
        _shelfLife: null,
        _productDate: null,
        productBatch: "",
        buyingPrice: item.price || 0,
        warehousingAmount: 0,
        //
        deliveryQuantity: 0,
        price: item.price,
        reason: "",
        amount: 0,
        //
        returnsQuantity: 0,
        discountAmount: 0,
        returnsAmount: 0,
        //
        adjustmentQuantity: 0,
        //
        profitLossQuantity: 0,
        profitLossAmount: 0,
        //
        orderAmount: 0,
        //
        saleQuantity: 0,
      });
    });
    productData.value = [...productData.value].concat(newData);
    productSelVisible.value = false;
    selProductIds.value = [];
  }
}
function removeProduct(index: number) {
  productData.value.splice(index, 1);
}
function isItemDisabled(record: ProductFileItem) {
  return !!productData.value.find((item) => item.productId === record.id);
}
/**
 * 确定新增或编辑
 */
function handleOk() {
  if (productData.value.length === 0) {
    return message.info("请至少选择一个商品");
  }
  if (wrFormIns.value) {
    wrFormIns.value.validate().then(async () => {
      const data: Partial<ReceiptItem> = { ...model.value };
      if (receiptTableIns.value) {
        const productData = receiptTableIns.value.getProductData();
        if (!productData) return;
        data.details = productData;
      } else {
        const details = cloneDeep(productData.value);
        for (let i = 0; i < details.length; i++) {
          const item = details[i];
          item.shelfLife = item._shelfLife?.valueOf();
          delete item._shelfLife;
          item.productDate = item._productDate?.valueOf();
          delete item._productDate;
        }
        data.details = details;
      }
      if (warehouseData.value && data.warehouseId) {
        const target = warehouseData.value.find((el) => el.id === data.warehouseId);
        if (target) {
          data.warehouse = target.name;
        }
      }
      data.warehousingAmount = summaryData.value?.warehousingAmount;
      data.warehousingQuantity = summaryData.value?.warehousingQuantity;
      data.deliveryAmount = summaryData.value?.amount;
      data.deliveryQuantity = summaryData.value?.deliveryQuantity;
      data.returnsAmount = summaryData.value?.returnsAmount;
      data.returnsQuantity = summaryData.value?.returnsQuantity;
      data.adjustmentAmount = summaryData.value?.amount;
      data.adjustmentQuantity = summaryData.value?.adjustmentQuantity;
      data.profitLossAmount = summaryData.value?.profitLossAmount;
      data.profitLossQuantity = summaryData.value?.profitLossQuantity;
      data.orderQuantity = summaryData.value?.orderQuantity;
      data.orderAmount = summaryData.value?.orderAmount;
      data.saleQuantity = summaryData.value?.saleQuantity;
      data.saleAmount = summaryData.value?.amount;
      if (data.warehousingDate) {
        data.warehousingDate = dayjs(data.warehousingDate).valueOf();
      }
      if (data.tabulationTime) {
        data.tabulationTime = dayjs(data.tabulationTime).valueOf();
      }
      if (data.deliveryDate) {
        data.deliveryDate = dayjs(data.deliveryDate).valueOf();
      }
      if (data.returnsDate) {
        data.returnsDate = dayjs(data.returnsDate).valueOf();
      }
      if (data.adjustmentDate) {
        data.adjustmentDate = dayjs(data.adjustmentDate).valueOf();
      }
      if (data.profitLossDate) {
        data.profitLossDate = dayjs(data.profitLossDate).valueOf();
      }
      if (data.saleDate) {
        data.saleDate = dayjs(data.saleDate).valueOf();
      }
      let re: any;
      if (props.wrId) {
        data.id = props.wrId;
        re = await updateWarehousingReceipt(data, props.receiptType);
      } else {
        re = await addWarehousingReceipt(data, props.receiptType);
      }
      if (re === undefined) {
        message.success("操作成功");
        handleVisible(false);
        props.reloadTable && props.reloadTable();
      }
    });
  }
}
/**
 * 审核信息 建单信息
 */
const tabulator = ref("--");
onMounted(() => {
  const info = authCache.getUserInfo();
  if (info) {
    tabulator.value = info.nickName || info.username || "";
  }
});
const tabulationTime = ref("--");
let inter: any = null;
function startTabulationTime() {
  clearInterval(inter);
  tabulationTime.value = dayjs().format("YYYY-MM-DD HH:mm:ss");
  inter = setInterval(() => {
    tabulationTime.value = dayjs().format("YYYY-MM-DD HH:mm:ss");
  }, 1000);
}
function stopTabulationTime() {
  clearInterval(inter);
  tabulationTime.value = "--";
}
const reviewer = ref("");
watch([reviewer, () => props.wrId], ([reviewer, wrId]) => {
  //已审核的不能编辑
  okDisabled.value = !!wrId && !!reviewer;
});
const reviewTime = ref("");
/**
 * 选择人员
 */
const operatorSelIns = ref<SelectExpose>();
function handleOperatorSel() {
  if (selOperatorIds.value.length === 0) {
    return message.info("请选择" + operatorText.value);
  }
  if (operatorSelIns.value) {
    const items = operatorSelIns.value.getSelecedItems() as UserItem[];
    model.value[operatorKey.value] = items[0].nickname;
    model.value[operatorKey.value + "Id"] = items[0].id;
  }
  operatorSelVisible.value = false;
}
const selOperatorIds = ref<number[]>([]);
const selOperatorColumns = ref<TableColumnProps[]>([
  {
    title: "账号",
    dataIndex: "username",
  },
  {
    title: "用户名称",
    dataIndex: "nickname",
  },
  {
    title: "隶属架构",
    dataIndex: "deptName",
  },
]);
</script>
